/************************************************************************
* Filename:				WinMain.cpp 
* Date Created:			04/29/2011                                 
* Mod. Date:			04/29/2011                                    
* Mod. Initials:		JW
* Author:				John Wileczek
* Purpose:				This is the entry point of
*						the game. The main game window will be initialized
*						here and needed info will passed off to CGame
*************************************************************************/
#include <windows.h>
//Include Memory Detection here

//Include CGame Here




const char* g_szWindowTitle		= "Schlep's Labyrinth";
const char* g_szClassName		= "APWindowClass";
const int	g_nWindowWidth		= 1024;
const int	g_nWindowHeight		= 768;

//Need to setup full screen if in release mode
#ifdef _DEBUG
	const BOOL g_bIsWindowed	= TRUE;
#else
	const BOOL g_bIsWindowed	= FALSE;
#endif


/*********************************************************************************
 * WindowProc():		Processes messages sent through WinMain message loop.   			      
 *
 * Ins:					hWnd
 *      				msg
 *						wParam
 *						lParam
 * Outs:		      
 *
 * Returns:				LPRESULT CALLBACK	      
 *
 * Mod. Date:		    04/29/2011  
 * Mod. Initials:	    JW  
 ********************************************************************************/
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	//main message handler for the system
	PAINTSTRUCT m_ps;
	HDC			 m_hdc;

	//check message
	switch(msg)
	{
	case WM_SYSKEYUP:
	case WM_SYSCHAR:
		return (0);
		break;
	case WM_CLOSE:
		{
			DestroyWindow(hWnd);
		}
		break;
	case WM_ACTIVATE:
		{
			//if window is gaining focus back
			if(LOWORD(wParam) != WA_INACTIVE)
			{
				//pause game message here(load pause state?)
			}
			else //losing focus (not the main wndow)
			{
				//unpause / pause toggle messgae (pop state?)
			}
		}
		break;
	case WM_CREATE:
		{
			//initialization area
			return (0);
		}
		break;
	case WM_PAINT:
		{
			//window painting begins
			m_hdc = BeginPaint(hWnd, &m_ps);

			//end window painting
			EndPaint(hWnd, &m_ps);
			return (0);
		}
	case WM_DESTROY:
		{
			//end application when destroy posted
			PostQuitMessage(0);
			return(0);
		}
		break;

	default:
		break;
	}

	//process any remaining messages
	return(DefWindowProc(hWnd, msg, wParam, lParam));
}
/*********************************************************************************
 * CheckIfAlreadyRunning():		Function Will check if the program is already running   
 * 								This will restore the window if it is running, 
 *								rather then starting a new one.	      
 *
 * Ins:			      
 *      		     
 * Outs:		      
 *
 * Returns:						BOOL	      
 *
 * Mod. Date:					04/29/2011
 * Mod. Initials:				JW
 ********************************************************************************/
BOOL CheckIfAlreadyRunning(void)
{
	//check if there is a window of this type and name
	HWND hWnd = FindWindow(g_szClassName, g_szWindowTitle);

	//if there is
	if(hWnd)
	{
		//check if it minimized, restore window
		if(IsIconic(hWnd))
			ShowWindow(hWnd, SW_RESTORE);
		//and set it to front window
		SetForegroundWindow(hWnd);

		return TRUE;
	}

	//if no copies running
	return FALSE;
}


/*********************************************************************************
 * RegisterWindowClass():		Registers the window class for the game   
 * 			      
 * Ins:			      
 *      		     
 * Outs:		      
 *
 * Returns:						BOOL      
 *
 * Mod. Date:					04/29/2011
 * Mod. Initials:				JW
 ********************************************************************************/
BOOL RegisterWindowClass(HINSTANCE hInstance)
{
	//describe the window class
	WNDCLASSEX winClassEx;

	//Window structure members
	winClassEx.cbSize		= sizeof(winClassEx);
	winClassEx.style		= CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	winClassEx.lpfnWndProc	= WindowProc;
	winClassEx.cbClsExtra   = 0;
	winClassEx.cbWndExtra   = 0;
	winClassEx.hInstance	= hInstance;
	winClassEx.hIcon		= LoadIcon(NULL, IDI_APPLICATION); //change this to set program icon
	winClassEx.hIconSm		= NULL;
	winClassEx.hCursor		= LoadCursor(NULL, IDC_ARROW);
	winClassEx.hbrBackground= (HBRUSH)GetStockObject(BLACK_BRUSH);
	winClassEx.lpszMenuName = NULL;
	winClassEx.lpszClassName= g_szClassName;

	//register our window class
	return RegisterClassEx(&winClassEx);
}


/*********************************************************************************
 * MakeWindow():		This function will create a window at the size needed 
 * 			      
 * Ins:					hInstance	      
 *      		     
 *
 * Outs:		      
 *
 * Returns:				HWND	      
 *
 * Mod. Date:			04/29/2011     
 * Mod. Initials:	    JW
 ********************************************************************************/
HWND MakeWindow(HINSTANCE hInstance)
{
	//establish window flags
	DWORD dwWindowStyleFlags = WS_VISIBLE;

	if(g_bIsWindowed)
	{
		//if the window is not fulscreen, style set to overlapped
		dwWindowStyleFlags |= WS_OVERLAPPEDWINDOW;
	}
	else
	{
		//if is fullscreen style sets to popup Cursor needed for game
		dwWindowStyleFlags |= WS_POPUP;
	}

	//create window rect from sizes
	RECT rWindow;
	rWindow.top = 0;
	rWindow.left = 0;
	rWindow.right = g_nWindowWidth;
	rWindow.bottom = g_nWindowHeight;

	//use ex functions to adjust the rect so that our
	//client area is our requested size

	AdjustWindowRectEx(&rWindow, dwWindowStyleFlags, FALSE, WS_EX_APPWINDOW); //this can be changed to add a menu if needed

	//collect the width and heigh from this newly stretched rect
	int nWindowWidth = rWindow.right - rWindow.left;
	int nWindowHeight = rWindow.bottom - rWindow.top;

	//Create and return the window with these set values
	return CreateWindowEx(WS_EX_APPWINDOW, g_szClassName, g_szWindowTitle, dwWindowStyleFlags,
						  (GetSystemMetrics(SM_CXSCREEN)/2) - (nWindowWidth/2),
						  (GetSystemMetrics(SM_CYSCREEN)/2) - (nWindowHeight/2),   //these two tell where to create the window, centered inthis case
						  nWindowWidth, nWindowHeight, NULL, NULL, hInstance, NULL);
}



/*********************************************************************************
 * WinMain():		This is the main program loop. The game will be initialized,   
 * 					shutdown, and updated here based on game events and messages.		      			      
 *
 * Ins:				hInstance
 *      		    hPrevInstance 
 *					lpCmdLine
 *					nCmdShow
 *
 * Outs:		      
 *
 * Returns:			int WINAPI		      
 *
 * Mod. Date:		04/29/2011		      
 * Mod. Initials:	JW      
 ********************************************************************************/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG		msg; //message used for the main
	HWND	hWnd;//handle to main window

	// PG2 memory detection goes here if we need it



	//Check for Other instances of game, and prevent them from being created
	if(!hPrevInstance)
	{
		if(CheckIfAlreadyRunning())
			return FALSE;
	}

	//Register the window class for use
	if(!RegisterWindowClass(hInstance)) //if the register returns null quit
		return 0;

	//creates the window;
	hWnd = MakeWindow(hInstance);

	if(!hWnd) //if hwnd is not created quit
		return 0;

	//show the window
	ShowWindow(hWnd, nCmdShow);

	//update the window
	UpdateWindow(hWnd);

	//Game Initialization here
	

	
	//Main Message Loop
	while(TRUE)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			//if the messgae is a quit message leave game loop
			if(msg.message == WM_QUIT)
				break;

			//Any accelerator message get processed here
			TranslateMessage(&msg);

			//message gets sent to the proc for handling
			DispatchMessage(&msg);
		}

		//check if game is still running
		//if not quit

	}

	//Shutdown the Game here
	

	//Unregister window class
	UnregisterClass(g_szClassName, hInstance);

	//quit back out to windows
	return(int)(msg.wParam);
}